package horse;

public class Area implements Cloneable
{
	private int[][] area;
	private int n, m;
	
	public Area ( int n, int m )
	{
		setSize( n, m );
	}
	
	public Area ()
	{
	}
	
	public void setSize( int n, int m  )
	{
		if ( n<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't create area. n<1");
		}
		
		if ( m<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't create area. m<1");
		}
		
		this.n=n+4;
		this.m=m+4;
		
		area = new int [n+4][m+4];
		
		for (int i=0; i<n+4; i++)
		{
			for (int j=0; j<2; j++)
			{
				area[i][0+j]=-3;
				area[i][m+3-j]=-3;
			}
		}
		
		for (int i=0; i<m+4; i++)
		{
			for (int j=0; j<2; j++)
			{
				area[0+j][i]=-3;
				area[n+3-j][i]=-3;
			}
		}
	}
	
	@Override
	public Area clone()
	{
		if ( (n-4)<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't create clone. n<1");
		}
		
		if ( (m-4)<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't create clone. m<1");
		}
		
		Area clone = new Area( n-4, m-4 );
		
		for (int i=2; i<n-2; i++)
		{
			for (int j=2; j<m-2; j++)
			{
				clone.area[i][j] = area[i][j];
			}
		}
		return clone;
	}
	
	public void setStartPoint( int x, int y )
	{
		x+=2;
		y+=2;
		
		if ( x>=(n-2) || x<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set start point. (n not valid)");
		}
		
		if ( y>=(m-2) || y<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set start point. (m not valid)");
		}
		
		area[x][y]=-1;
	}
	
	public void setEndPoint( int x, int y )
	{
		x+=2;
		y+=2;
		
		if ( x>=(n-2) || x<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set end point. (n not valid)");
		}
		
		if ( y>=(m-2) || y<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set end point. (m not valid)");
		}
		
		area[x][y]=-2;
	}
	
	public boolean checkEnd( int x, int y )
	{
		if ( n<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check end point. n<1");
		}
		
		if ( m<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check end point. m<1");
		}
		
		if ( x>=n || x<0 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check end point. (x not valid)");
		}
		
		if ( y>=m || y<0 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check end point. (y not valid)");
		}
		
		if (area[x][y]==-2) 
		{
			return true;
		}
		return false;
	}
	
	public void setValue( int x, int y, int value )
	{
		if ( n<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set value. n<1");
		}
		
		if ( m<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set value. m<1");
		}
		
		if ( x>=(n-2) || x<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set value. (x not valid)");
		}
		
		if ( y>=(m-2) || y<2 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set value. (y not valid)");
		}
		
		if ( value<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't set value. (value not valid)");
		}
		
		area[x][y]=value;
	}
	
	public boolean checkStep( int x ,int y)
	{
		if ( n<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check step. n<1");
		}
		
		if ( m<1 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check step. m<1");
		}
		
		if ( x>=n || x<0 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check step. (x not valid)");
		}
		
		if ( y>=m || y<0 ) 
		{
			throw new ArrayIndexOutOfBoundsException("Can't check step. (y not valid)");
		}
		
		if (area[x][y]==0) 
		{
			return true;
		}
		return false;
	}
	
	public int size()
	{
		return n*m;
	}
	
	public void view ()
	{
		System.out.println("S - start point, E -end point\n");
		
		for (int i=2; i<n-2; i++)
		{
			for (int j=2; j<m-2; j++)
			{
				System.out.print(area[i][j]==-1 ? "S " : area[i][j]==-2 ? "E " : area[i][j]+" ");
			}
			System.out.println();
		}
	}
	
	public int [][] getArray()
	{
		return area;
	}
}
